package com.baayso.bms2.config.spring;

import java.sql.SQLException;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

import com.alibaba.druid.pool.DruidDataSource;
import com.baayso.bms2.core.log.Log;

/**
 * 数据源配置。
 * 
 * @author ChenFangjie(2015年9月19日 下午9:32:45)
 * 
 * @since 1.0.0
 * 
 * @version 1.0.0
 * 
 */
@Configuration
@PropertySource("classpath:jdbc.properties") // 加载资源文件
public class DataSourceConfig {

    private static final Logger log = Log.get();

    @Inject
    private Environment env;

    // @Value("${jdbc.driverClassName}")
    // private String driverClassName;
    //
    // @Value("${jdbc.url}")
    // private String url;
    //
    // @Value("${jdbc.username}")
    // private String username;
    //
    // @Value("${jdbc.password}")
    // private String password;
    //
    // @Value("${druid.initialSize}")
    // private int druidInitialSize; // 初始化大小
    //
    // @Value("${druid.minIdle}")
    // private int druidMinIdle; // 最小连接
    //
    // @Value("${druid.maxActive}")
    // private int druidMaxActive; // 最大连接
    //
    // @Value("${druid.maxWait}")
    // private long druidMaxWait; // 获取连接等待超时的时间
    //
    // @Value("${druid.timeBetweenEvictionRunsMillis}")
    // private long druidTimeBetweenEvictionRunsMillis; // 间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
    //
    // @Value("${druid.minEvictableIdleTimeMillis}")
    // private long druidMinEvictableIdleTimeMillis; // 一个连接在池中最小生存的时间，单位是毫秒
    //
    // @Value("${druid.validationQuery}")
    // private String druidValidationQuery;
    //
    // @Value("${druid.testWhileIdle}")
    // private boolean druidTestWhileIdle;
    //
    // @Value("${druid.testOnBorrow}")
    // private boolean druidTestOnBorrow;
    //
    // @Value("${druid.testOnReturn}")
    // private boolean druidTestOnReturn;
    //
    // // 如果用Oracle，则把poolPreparedStatements配置为true，mysql可以配置为false。分库分表较多的数据库，建议配置为false
    // @Value("${druid.poolPreparedStatements}")
    // private boolean druidPoolPreparedStatements;
    //
    // // 只要maxPoolPreparedStatementPerConnectionSize > 0, poolPreparedStatements就会被自动设定为true，使用oracle时可以设定此值
    // @Value("${druid.maxPoolPreparedStatementPerConnectionSize}")
    // private int druidMaxPoolPreparedStatementPerConnectionSize;
    //
    // @Value("${druid.filters}")
    // private String druidFilters; // 监控统计拦截的filters
    //
    // @Value("${druid.removeAbandoned}")
    // private boolean druidRemoveAbandoned; // 是否打开连接泄露自动检测
    //
    // @Value("${druid.removeAbandonedTimeoutMillis}")
    // private long druidRemoveAbandonedTimeoutMillis; // 连接长时间没有使用，被认为发生泄露时长
    //
    // @Value("${druid.logAbandoned}")
    // private boolean druidLogAbandoned; // 发生泄露时是否需要输出 log，建议在开启连接泄露检测时开启，方便排错

    // @Bean(name = "dataSource")
    // public DataSource dataSource() {
    // log.info("DataSource");
    //
    // DriverManagerDataSource dataSource = new DriverManagerDataSource();
    // dataSource.setDriverClassName(this.driverClassName);
    // dataSource.setUrl(this.url);
    // dataSource.setUsername(this.username);
    // dataSource.setPassword(this.password);
    //
    // return dataSource;
    // }

    @Bean(initMethod = "init", destroyMethod = "close")
    public DruidDataSource druidDataSource() throws SQLException {
        log.info("DruidDataSource");

        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(this.env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(this.env.getProperty("jdbc.url"));
        dataSource.setUsername(this.env.getProperty("jdbc.username"));
        dataSource.setPassword(this.env.getProperty("jdbc.password"));
        // 初始化大小
        dataSource.setInitialSize(this.env.getProperty("druid.initialSize", Integer.class, 10));
        // 最小连接
        dataSource.setMinIdle(this.env.getProperty("druid.minIdle", Integer.class, 10));
        // 最大连接
        dataSource.setMaxActive(this.env.getProperty("druid.maxActive", Integer.class, 100));
        // 获取连接等待超时的时间
        dataSource.setMaxWait(this.env.getProperty("druid.maxWait", Long.class, 60000L));
        // 间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
        dataSource.setTimeBetweenEvictionRunsMillis(this.env.getProperty("druid.timeBetweenEvictionRunsMillis", Long.class, 60000L));
        // 一个连接在池中最小生存的时间，单位是毫秒
        dataSource.setMinEvictableIdleTimeMillis(this.env.getProperty("druid.minEvictableIdleTimeMillis", Long.class, 300000L));
        dataSource.setValidationQuery(this.env.getProperty("druid.validationQuery", "SELECT 'x'"));
        dataSource.setTestWhileIdle(this.env.getProperty("druid.testWhileIdle", Boolean.class, Boolean.TRUE));
        dataSource.setTestOnBorrow(this.env.getProperty("druid.testOnBorrow", Boolean.class, Boolean.FALSE));
        dataSource.setTestOnReturn(this.env.getProperty("druid.testOnReturn", Boolean.class, Boolean.FALSE));
        // 如果用Oracle，则把poolPreparedStatements配置为true，mysql可以配置为false。分库分表较多的数据库，建议配置为false
        dataSource.setPoolPreparedStatements(this.env.getProperty("druid.poolPreparedStatements", Boolean.class, Boolean.FALSE));
        // 只要maxPoolPreparedStatementPerConnectionSize > 0, poolPreparedStatements就会被自动设定为true，使用oracle时可以设定此值
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(this.env.getProperty("druid.maxPoolPreparedStatementPerConnectionSize", Integer.class, 20));
        // 监控统计拦截的filters
        dataSource.setFilters(this.env.getProperty("druid.filters", "stat,wall"));
        // 是否打开连接泄露自动检测
        dataSource.setRemoveAbandoned(this.env.getProperty("druid.removeAbandoned", Boolean.class, Boolean.TRUE));
        // 连接长时间没有使用，被认为发生泄露时长
        dataSource.setRemoveAbandonedTimeoutMillis(this.env.getProperty("druid.removeAbandonedTimeoutMillis", Long.class, 300000L));
        // 发生泄露时是否需要输出 log，建议在开启连接泄露检测时开启，方便排错
        dataSource.setLogAbandoned(this.env.getProperty("druid.logAbandoned", Boolean.class, Boolean.TRUE));
        // dataSource.setUrl(this.url);
        // dataSource.setUsername(this.username);
        // dataSource.setPassword(this.password);
        // // 初始化大小
        // dataSource.setInitialSize(this.druidInitialSize);
        // // 最小连接
        // dataSource.setMinIdle(this.druidMinIdle);
        // // 最大连接
        // dataSource.setMaxActive(this.druidMaxActive);
        // // 获取连接等待超时的时间
        // dataSource.setMaxWait(this.druidMaxWait);
        // // 间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
        // dataSource.setTimeBetweenEvictionRunsMillis(this.druidTimeBetweenEvictionRunsMillis);
        // // 一个连接在池中最小生存的时间，单位是毫秒
        // dataSource.setMinEvictableIdleTimeMillis(this.druidMinEvictableIdleTimeMillis);
        // dataSource.setValidationQuery(this.druidValidationQuery);
        // dataSource.setTestWhileIdle(this.druidTestWhileIdle);
        // dataSource.setTestOnBorrow(this.druidTestOnBorrow);
        // dataSource.setTestOnReturn(this.druidTestOnReturn);
        // // 如果用Oracle，则把poolPreparedStatements配置为true，mysql可以配置为false。分库分表较多的数据库，建议配置为false
        // dataSource.setPoolPreparedStatements(this.druidPoolPreparedStatements);
        // // 只要maxPoolPreparedStatementPerConnectionSize > 0, poolPreparedStatements就会被自动设定为true，使用oracle时可以设定此值
        // dataSource.setMaxPoolPreparedStatementPerConnectionSize(this.druidMaxPoolPreparedStatementPerConnectionSize);
        // // 监控统计拦截的filters
        // dataSource.setFilters(this.druidFilters);
        // // 是否打开连接泄露自动检测
        // dataSource.setRemoveAbandoned(this.druidRemoveAbandoned);
        // // 连接长时间没有使用，被认为发生泄露时长
        // dataSource.setRemoveAbandonedTimeoutMillis(this.druidRemoveAbandonedTimeoutMillis);
        // // 发生泄露时是否需要输出 log，建议在开启连接泄露检测时开启，方便排错
        // dataSource.setLogAbandoned(this.druidLogAbandoned);

        return dataSource;
    }

}
